package com.xj.spring.quartz;

import org.apache.log4j.Logger;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * author: xiajun
 * Date: 2014-06-23
 * Time: 21-06-00
 */
public class QuartzDemo {
    private final static Logger LOGGER = Logger.getLogger(QuartzDemo.class);
    private final static QuartzDemo quartz = new QuartzDemo();
    private static SchedulerFactory schedulerFactory;
    private final static String JOBGROUP = "JOB_GROUP";
    private final static String TRIGGERGROUP = "TRIGGER_GROUP";
    private static Scheduler sched;

    private QuartzDemo() {
        schedulerFactory = new StdSchedulerFactory();
        try {
            sched = schedulerFactory.getScheduler();
        } catch (SchedulerException e) {
            LOGGER.error("init QuartzDemo error.", e);
        }
    }

    /**
     * 添加一个定时器
     *
     * @param triggerName 定时器名称
     * @param time        运行时间
     * @param job         需要运行的job
     * @param obj         运行时的参数
     * @throws SchedulerException
     */
    public void addJob(String triggerName, Date time, Job job,Object obj) throws SchedulerException {
        JobDataMap newJobDataMap =new JobDataMap();
        newJobDataMap.put("service",obj);
        JobDetail jobDetail = JobBuilder.newJob(job.getClass()).withIdentity(triggerName, JOBGROUP).setJobData(newJobDataMap).build();
        Trigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerName, TRIGGERGROUP).startAt(time).build();//.withSchedule(cb)
        sched.scheduleJob(jobDetail, cronTrigger);
        if (!sched.isShutdown()) {
            sched.start();
        }
    }
    /**
     * 添加一个定时器
     *
     * @param triggerName 定时器名称
     * @param time        运行时间
     * @param job         需要运行的job
     * @throws SchedulerException
     */
    public void addJob(String triggerName, Date time, Job job) throws SchedulerException {
        JobDataMap newJobDataMap =new JobDataMap();
        newJobDataMap.put("service","test");
        JobDetail jobDetail = JobBuilder.newJob(job.getClass()).withIdentity(triggerName, JOBGROUP).setJobData(newJobDataMap).build();
        Trigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerName, TRIGGERGROUP).startAt(time).build();//.withSchedule(cb)
        sched.scheduleJob(jobDetail, cronTrigger);
        if (!sched.isShutdown()) {
            sched.start();
        }
    }
    /**
     * 重置一个表达式，修改运行策略
     *
     * @param triggerName 表达式名称
     * @param time        执行表达式
     * @throws SchedulerException
     */
    public void resetJob(String triggerName, Date time) throws SchedulerException {
        TriggerKey tk = new TriggerKey(triggerName, TRIGGERGROUP);
        if(sched.isShutdown()){
         return;
        }
        Trigger trigger = sched.getTrigger(tk);
        if (trigger != null) {
            JobKey jk = new JobKey(triggerName, JOBGROUP);
            JobDetail jobDetail = sched.getJobDetail(jk);
            removeJob(triggerName);
            Trigger ct = TriggerBuilder.newTrigger().withIdentity(tk).startAt(time).build();
            sched.scheduleJob(jobDetail, ct);
            if (!sched.isShutdown())
                sched.start();
        } else {
            LOGGER.warn("not found triggerName=" + trigger + " trigger");
        }
    }

    /**
     * 删除旧定时器
     *
     * @param triggerName 定时器名称
     * @throws SchedulerException
     */
    public void removeJob(String triggerName) throws SchedulerException {
        TriggerKey tk = new TriggerKey(triggerName, TRIGGERGROUP);
        sched.pauseTrigger(tk);// 停止触发器
        sched.unscheduleJob(tk);// 移除触发器
        JobKey jk = new JobKey(triggerName, JOBGROUP);
        sched.deleteJob(jk);// 删除任务
    }

    /**
     * 关闭调度器 未执行的任务也将被关闭
     *
     * @throws SchedulerException
     */
    public void shoutdown() throws SchedulerException {
        sched.shutdown();
    }

    /**
     * 查看真在运行的任务
     * @throws SchedulerException
     */
    public void getRunJob() throws SchedulerException {
        List<JobExecutionContext> executingJobs = sched.getCurrentlyExecutingJobs();
        for (JobExecutionContext executingJob : executingJobs) {
            JobDetail jobDetail = executingJob.getJobDetail();
            JobKey jobKey = jobDetail.getKey();
            Trigger trigger = executingJob.getTrigger();
            System.out.print("jobkey=" + jobKey.getName() + " jobgroup=" + jobKey.getGroup() + " triggerkey=" + trigger.getKey());
            Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
            System.out.print(" state=" + triggerState.name());
            if (trigger instanceof CronTrigger) {
                CronTrigger cronTrigger = (CronTrigger) trigger;
                String cronExpression = cronTrigger.getCronExpression();
                System.out.print(" cron=" + cronExpression);
            }
            System.out.println("");
        }
        System.out.println("getRunJob end.");
    }

    /**
     * 查看准备就绪的任务
     * @throws SchedulerException
     */
    public void getPrepareJob() throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = sched.getJobKeys(matcher);
        for (JobKey jobKey : jobKeys) {
            List<? extends Trigger> triggers = sched.getTriggersOfJob(jobKey);
            for (Trigger trigger : triggers) {
                System.out.print("jobkey=" + jobKey.getName() + " jobgroup=" + jobKey.getGroup() + " triggerkey=" + trigger.getKey());
                Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
                System.out.print(" state=" + triggerState.name());
                if (trigger instanceof CronTrigger) {
                    CronTrigger cronTrigger = (CronTrigger) trigger;
                    String cronExpression = cronTrigger.getCronExpression();
                    System.out.print(" cron=" + cronExpression);
                }
            }
            System.out.println("");
        }
        System.out.println("getPrepareJob end.");
    }

    /**
     * 类的唯一实例
     *
     * @return
     */
    public static QuartzDemo getInstance() {
        return quartz;
    }


    public static void main(String[] args) throws SchedulerException, InterruptedException {
        getInstance().addJob("triggerName1", new Date(new Date().getTime() + 3000), new TestJob());//3秒后执行
        getInstance().addJob("triggerName2", new Date(new Date().getTime() + 3000), new Test2Job());
        Thread.sleep(2000);
        System.out.println("========================");
        getInstance().resetJob("triggerName1", new Date(new Date().getTime() + 10000));//修改为10秒后执行
        getInstance().getPrepareJob();
        Thread.sleep(10000);
        getInstance().getPrepareJob();
        getInstance().getRunJob();
        System.exit(0);
    }
}
